package cn.skyclass.net
{
	import flash.utils.Dictionary;
	
	import mx.controls.Alert;
	import mx.messaging.ChannelSet;
	import mx.messaging.channels.AMFChannel;
	import mx.rpc.AbstractOperation;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.remoting.RemoteObject;

	/**
	 * 
	 * @author syg
	 * 
	 * 使用Dic存储RemoteObject对象
	 * 
	 * 使用方法，
	 * 
	 */ 
	public class RoFactory
	{	
		private static var _instance:RoFactory = null;
			
		public static function getInstance():RoFactory{
			if(_instance == null) {
				_instance = new RoFactory();
			}
			return _instance;
		}
				
		private var _roDic:Dictionary = new Dictionary();
		private var _channelset:ChannelSet = new ChannelSet();
		private var _contextUrl:String = "";
								
		public function init(url:String):void{
			if(url.charAt(url.length - 1) != '/') {
				url += '/';
			}
			var channel:AMFChannel = new AMFChannel();
			channel.url = url + "messagebroker/amf";
			_channelset.addChannel(channel);
		}
		
		public function get initialized():Boolean{
			return _channelset.channels.length > 0;
		}
		
		protected function beginCall(status:String):void {
			
		}
		
		protected function callSuccess(status:String):void {
		}
		
		protected function callFail(status:String):void{
			Alert.show(status + "失败!", "错误");
		}
		
		private function _getRemoteObject(name:String):RemoteObject {
			var ro:RemoteObject = _roDic[name];
			if(ro == null) {
				ro = new RemoteObject();
				ro.channelSet = _channelset;
				ro.destination = name;
				
				_roDic[name] = ro;
			}
			return ro;					
		}
		
		public function callFunction(roName:String, resultHandler:Function, status:String, 
			functionName:String, ... args):void{
			
			beginCall(status);
			
			var ro:RemoteObject = _getRemoteObject(roName);
				
			var operation:AbstractOperation = ro.getOperation(functionName);
			operation.arguments = args;
			operation.addEventListener(ResultEvent.RESULT, _onResult);
			operation.addEventListener(FaultEvent.FAULT, _onFault);
			operation.send();								

			function _onResult(e:ResultEvent):void{
				_removeEventListener();				
				resultHandler(e);
				
				callSuccess(status);
			}
			
			function _onFault(e:FaultEvent):void {				
				_removeEventListener();
				
				callFail(status);
			}
			
			function _removeEventListener():void{
				operation.removeEventListener(FaultEvent.FAULT, _onFault);
				operation.removeEventListener(ResultEvent.RESULT, _onResult);				
			}
		}
	}
}